/**
 * API调用Hook
 * 提供统一的API调用、错误处理和状态管理
 */

import { useState, useCallback } from 'react'
import { useToast } from '@/hooks/use-toast'
import { ApiResponse, ApiError } from '../types/api'
import { AxiosError } from 'axios'

interface UseApiCallOptions {
  showToast?: boolean
  autoRetry?: boolean
  retryCount?: number
  onSuccess?: (data: any) => void
  onError?: (error: ApiError) => void
}

interface UseApiCallReturn<T> {
  data: T | null
  isLoading: boolean
  error: ApiError | null
  execute: (...args: any[]) => Promise<T | null>
  reset: () => void
}

/**
 * API调用Hook
 * @param apiFunction API函数
 * @param options 选项配置
 * @returns API调用状态和方法
 */
export function useApiCall<T>(
  apiFunction: (...args: any[]) => Promise<ApiResponse<T>>,
  options: UseApiCallOptions = {}
): UseApiCallReturn<T> {
  const {
    showToast = false,
    autoRetry = false,
    retryCount = 3,
    onSuccess,
    onError,
  } = options

  const [data, setData] = useState<T | null>(null)
  const [isLoading, setIsLoading] = useState(false)
  const [error, setError] = useState<ApiError | null>(null)
  const { toast } = useToast()

  const execute = useCallback(
    async (...args: any[]): Promise<T | null> => {
      setIsLoading(true)
      setError(null)

      let attempts = 0
      const maxAttempts = autoRetry ? retryCount : 1

      while (attempts < maxAttempts) {
        try {
          const response = await apiFunction(...args)

          // 判断成功：code === 200
          if (response.code === 200) {
            setData(response.data)
            onSuccess?.(response.data)

            if (showToast) {
              toast({
                title: '操作成功',
                description: response.msg || '请求完成',
                duration: 3000,
              })
            }

            setIsLoading(false)
            return response.data
          } else {
            throw new Error(response.msg || '请求失败')
          }
        } catch (err) {
          attempts++
          
          const apiError: ApiError = {
            code: 500,
            message: '请求失败',
          }

          if (err instanceof AxiosError) {
            apiError.code = err.response?.status || 500
            apiError.message = err.response?.data?.msg || err.message
            apiError.details = err.response?.data
          } else if (err instanceof Error) {
            apiError.message = err.message
          }

          if (attempts >= maxAttempts) {
            setError(apiError)
            onError?.(apiError)
            
            if (showToast) {
              toast({
                title: '操作失败',
                description: apiError.message,
                variant: 'destructive',
                duration: 3000,
              })
            }
            
            setIsLoading(false)
            return null
          }

          // 重试延迟
          if (attempts < maxAttempts) {
            await new Promise(resolve => setTimeout(resolve, 1000 * attempts))
          }
        }
      }

      setIsLoading(false)
      return null
    },
    [apiFunction, autoRetry, retryCount, onSuccess, onError, showToast, toast]
  )

  const reset = useCallback(() => {
    setData(null)
    setError(null)
    setIsLoading(false)
  }, [])

  return {
    data,
    isLoading,
    error,
    execute,
    reset,
  }
}